#pragma once
#include"HashTable.h"

using namespace std;


namespace linhui
{
	template<class T>
	struct HashFunc_m
	{
		size_t operator()(const T& item)
		{
			return item;
		}
	};

	template<>
	struct HashFunc_m<string>
	{

		size_t operator()(const string& item)
		{
			size_t ret = 0;
			for (const auto& au : item)
			{
				ret += au;
				ret *= 131;
			}
			return ret;
		}
	};

	template<class Key , class Val, class HashFunc = HashFunc_m<Key>>
	class unordered_map
	{
	public:
		struct KeyOfVal
		{
			Key operator()(const pair<Key,Val>& input)
			{
				return input.first;
			}
		};
		using iterator = typename HashTable<Key, pair<Key, Val>, KeyOfVal, HashFunc>::iterator;
		pair<iterator, bool> Insert(const pair<Key, Val>& input)
		{
			return _self.Insert(input);
		}

		iterator begin()
		{
			return _self.begin();
		}
		iterator end()
		{
			return _self.end();
		}

		iterator find(const Key& key)
		{
			return _self.Find(key);
		}
		size_t count(const Key& key)
		{
			return _self.Count(key);
		}
		bool erase(const Key& key)
		{
			return _self.Erase(key);
		}

		size_t size()
		{
			return _self.size();
		}
		bool empty()
		{
			return _self.size() == 0;
		}

		Val& operator[](const Key& key)
		{
			pair<iterator, bool> ret = _self.Insert({key,Val()});
			return (*ret.first).second;
		}

	private:
		HashTable < Key,pair<Key,Val> , KeyOfVal , HashFunc > _self;
	};
}